home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
graphics
/
mdl10.zoo
/
flicker.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-06
|
24KB
|
1,132 lines
/*
* flicker.c - display grayscale image with flicker mode
*
* modified for dl/gl files. pimg points to all the raw images and
* nframes is the number of frames. no histogram stuff at all. handles
* dl commands (which is a list of frame indices in order).
*
* note: I16 is 16 bit integer so we don't care what an "int" is
* external to this routine. when u see 96000, it is really
* 48000 * sizeof(I16). most things here are actually tuned to 16 bit
* ints.
*
* now ansi for gcc. -mshort not needed.
*
* compilation control:
* NEW_RANDOM def to use new random noise code
* NO_INVERT def to invert pixel intensities (normally
* undefined)
*/
typedef short I16;
typedef unsigned short UI16;
#ifndef lint
static char *rcsid = "$Id: flicker.c,v 1.3 1991/07/24 17:13:48 rosenkra Exp $";
#endif
/*
* $Log: flicker.c,v $
* Revision 1.3 1991/07/24 17:13:48 rosenkra
* now RCS. fix flicker for SimpConv2Gray so image is not so dark. also
* make sure last work in each pixel row gets dumped to screen when
* using SimpConv2Gray (e.g. during cut or zoom).
*
* Revision 1.2 1991/07/16 23:24:48 rosenkra
* released june 91 to usenet. first RCS revision.
*
*/
/*
* this is for screen-switching on mono to simulate grayscale. it
* uses a combination of floyd-steinberg and simulate "planes" which
* get displayed each vblank. the image it works from should be
* grayscale, i.e. each pixel is represented by an 8-bit (0 to 255)
* intensity. since GIF images come with a color table, it is first
* required to map each GIF pixel to the color table which has been
* first changed to grayscale, either by averaging the rgb values
* or by using the NTSC intensity equation.
*
* note that i think the f-s algorithm employed here sweeps each row
* left to right rather than alternating directions. that is why there
* is spurious info in areas otherwise supposed to be white.
*
* also, all points where chars are used in a calculation, they MUST
* be unsigned.
*
* return ptr to screens.
*/
/* written by Klaus Pedersen (micro@imada.dk) */
/* modified by Bill Rosenkranz (rosenkra@convex.com) */
#include <stdio.h>
#include <types.h>
#include <stdlib.h> /* for malloc */
#include <string.h> /* for bzero */
#include <osbind.h>
#define LEVELS 4
#define NUMERRS 1024
#define SCRNSPACE 48256L /* now per frame */
#define MAXFRAMES 25 /* 25 needs 2.4 MB (96000B/frame) */
/*
* globals.
*
* these are the thresholds for quantizing. 0,85,170,255 seem best
*/
static I16 _Levels[LEVELS] = { 0, 85, 170, 255};
static I16 _SimpLevels[LEVELS] = { 0, 255};
static int _Show; /* print progress to stdout if !=0 */
static int _Delay; /* ms delay between frames (if +ve) */
static I16 _Nframes; /* number of frames in raster */
static I16 _Ncommands; /* number of commands */
static I16 _Width; /* image size */
static I16 _Hight;
static I16 _Beta; /* for the Laplace filter */
static I16 _MaxRandom; /* for adding random noise */
static I16 *_Err1, /* the error propagation arrays */
*_Err2;
static I16 _Err1Array[NUMERRS],
_Err2Array[NUMERRS];
static I16 *_Scrn, /* we malloc space here */
*_Scrn1[MAXFRAMES],
*_Scrn2[MAXFRAMES],
*_Scrn3[MAXFRAMES];
/*
* local functions
*/
static void _Conv2Gray (unsigned char *, int *);
static void _SimpConv2Gray (unsigned char *, int *);
static I16 _GenConvPix (unsigned char *, int, int);
static I16 _SimpGenConvPix (unsigned char *, int, int);
static I16 _Laplace (unsigned char *);
static void _ClearErr (void);
static I16 _Rand (I16);
/*------------------------------*/
/* dl_flicker */
/*------------------------------*/
int dl_flicker (unsigned char *pimg, int nframes, int width, int hight,
int beta, int maxrandom, int opt, int delay, int *cmd,
int ncommands, int show)
/* pimg -> raster image sequence (intensities) */
/* nframes number of frames in pimg */
/* width width, pixels */
/* hight height, pixels */
/* beta for laplace filter */
/* maxrandom for random noise */
/* opt 0=no flicker, 1=flicker */
/* delay ms delay between images */
/* cmd -> commands (order to display frames) */
/* ncommands number of commands (total frames in loop) */
/* show print info to stdout if != 0 */
{
/*
* this is the main entry point. complete grayscale raster image
* comes from pimg with height and width specified. if beta != 0,
* do Laplace filter with that beta. if maxrandom != 0, add some
* random noise with that value (see below).
*
* pimg contains each basic frame in succession.
*
* dl commands are used. do this in loop showing the basic screens
* by indexing into _Scrn* as _Scrn*[cmd[i]].
*
* return 0 if ok. 1 if error.
*/
/*
* set our globals
*/
_Show = show;
_Nframes = (I16) nframes; /* number of frames in raster */
_Ncommands = (I16) ncommands; /* number of commands in animation */
_Delay = delay; /* ms delay between frames */
_Hight = (I16) hight; /* its height... */
_Width = (I16) width; /* ...and width */
_Beta = (I16) beta; /* Laplace filter coefficient */
/* 1=0.25, 2=0.50, 3=0.75... (Try 4) */
_MaxRandom = (I16) maxrandom; /* amount of random noise, 0-255 */
/* for 0% to 100% noise. (Try 10) */
/*
* check nframes.
*/
if (_Show)
printf ("flicker: num frames = %d, max allowed = %d\n",
_Nframes, MAXFRAMES);
if (_Nframes > MAXFRAMES)
_Nframes = MAXFRAMES;
/*
* allocate space for all screens. note that sizeof(I16) is 2.
*/
if (opt)
{
if (_Show)
printf ("flicker: allocating memory, flicker mode (%ld bytes)\n",
96000L * (long)_Nframes);
_Scrn = (I16 *) malloc (96000 * (size_t) _Nframes + 256);
}
else
{
if (_Show)
printf ("flicker: allocating memory, not flicker (%ld bytes)\n",
32000L * (long)_Nframes);
_Scrn = (I16 *) malloc (32000 * (size_t) _Nframes + 256);
}
if (_Scrn == (I16 *) NULL)
{
if (_Show)
printf ("flicker: memory allocation failed\n");
return (1);
}
/*
* make sure screen is aligned on 256-byte boundary.
*/
_Scrn = (I16 *) (((long) _Scrn + 256L) & 0xFFFFFF00L);
/*
* clear screens. this may not have to be done if malloc clears
* or if the dithering touches everything
*/
if (_Show)
printf ("flicker: clearing memory...\n");
if (opt)
bzero (_Scrn, (size_t) (96000 * _Nframes));
else
bzero (_Scrn, (size_t) (32000 * _Nframes));
/*
* do it!
*/
if (opt)
_Conv2Gray (pimg, cmd);
else
_SimpConv2Gray (pimg, cmd);
return (0);
}
/*------------------------------*/
/* _Conv2Gray */
/*------------------------------*/
static void _Conv2Gray (unsigned char *pic, int *cmd)
{
unsigned char *ppic;
register int i;
int j;
register I16 x;
I16 y;
I16 w;
I16 h;
register long yoffset;
I16 *TmpErr;
register I16 q;
I16 rover1;
I16 rover2;
register UI16 pix;
unsigned char *p;
char *old1;
char *old2;
int rpt;
int done;
/*
* number of times to repeat inner display loop showing a single
* frame. this is to deal with different frame rates. 40 ms for
* three Setscreen/Vsync is about right on 8MHz ST...
*/
rpt = _Delay / 40;
/*
* save old screen info
*/
old1 = (char *) Logbase ();
old2 = (char *) Physbase ();
/*
* clear...
*/
if (_Show)
printf ("flicker: clear screen...\n");
bzero (old1, (size_t) 32000);
bzero (old2, (size_t) 32000);
/*
* we will set physbase to our buffer and _Scrn1[0] points to it.
* set the other screen pointers. _Scrn is a buffer large enuf
* to hold all 3 screens for every frame. it would obviously be
* more efficient to blit the images rather than store the entire
* screen if the image is smaller than the entire screen.
*